import validator from 'validator';
import { Op } from 'sequelize';
import models from '../../models';
import { QueryWhereConf, AddRoleError, Item } from 'definitions/role';
import { QueryAllConf } from 'definitions/common';
import { initRedis } from '../../bin/init';

const { AdminPermission, AdminRole, AdminUser, AdminAccessRouter } = models;

export default function (router) {
  /**
   * 获取角色列表
   * @param {String} name 角色名称
   * @param {String} sign 角色类型
   * @param {Boolean} all 是否查询全部
   * @param {Number} page 查询页数
   * @param {Number} limit 每页限制数
   */
  router.get('/api/admin/role', async ctx => {
    const { name, sign, sorter, all } = ctx.request.query;
    const { page, limit } = ctx.parsePageAndLimit(ctx.request.query);

    let whereConf: QueryWhereConf = {};
    if (name) {
      whereConf.name = {
        [Op.like]: `%${name}%`
      };
    }

    if (sign) {
      whereConf.sign = {
        [Op.like]: `%${sign}%`
      };
    }

    // 排序规则
    let order = [['created_at', 'DESC']];
    if (sorter) {
      const sortName = sorter.split('_')[0].replace('createdAt', 'created_at').replace('updatedAt', 'updated_at');
      const sortFunc = sorter.split('_')[1].replace('ascend', 'ASC').replace('descend', 'DESC');
      order = [[sortName, sortFunc]];
    }

    // 是否获取全部数据
    const allConf: QueryAllConf = {};
    if (!all) {
      allConf.offset = (page - 1) * limit;
      allConf.limit = limit;
    }

    const roles = await AdminRole.findAndCountAll({
      ...allConf,
      where: whereConf,
      order: order
    });

    // 对权限分类做统计
    const data: Item[] = [];
    for (let i = 0; i < roles.rows.length; i++) {
      const permissions = await AdminRole.getPermissions(roles.rows[i].id);
      // 对权限分组统计
      let stat: { name: string; num: number }[] = [];
      let roleIds: number[] = [];
      for (let j = 0; j < permissions.length; j++) {
        roleIds.push(permissions[j].id);
        let curIndex = -1;
        const isInStat = stat.some((item, index) => {
          if (item.name === permissions[j].classify || (!permissions[j].classify && item.name === '其他')) {
            curIndex = index;
            return true;
          }
          return false;
        });
        if (isInStat) {
          stat[curIndex].num = stat[curIndex].num + 1;
        } else {
          stat.push({
            name: permissions[j].classify || '其他',
            num: 1
          });
        }
      }
      data.push({
        id: roles.rows[i].id,
        name: roles.rows[i].name,
        description: roles.rows[i].description,
        sign: roles.rows[i].sign,
        permissions: roleIds,
        stat: stat.map(item => `${item.name}(${item.num}个)`).join('、'),
        createdAt: roles.rows[i].createdAt,
        updatedAt: roles.rows[i].updatedAt
      });
    }

    await ctx.json(true, '获取权限成功', { total: roles.count, list: data });
  });

  /**
   * 新增角色
   * @param {String} name 角色名称
   * @param {String} sign 角色类型
   * @param {String} permissions 角色权限
   * @param {String} description 角色描述
   */
  router.post('/api/admin/role', async ctx => {
    let { name = '', sign = 'user', description = '', permissions = [] } = ctx.request.body;
    // 验证参数
    let error: AddRoleError = {};
    if (!name || !validator.isLength(name, { min: 2, max: 10 })) error.name = '角色名称格式错误';
    if (await AdminRole.isRepeat('name', name)) error.name = '角色名称重复';
    if (permissions.length === 0) error.permissions = '请选择角色权限';
    if (!sign) error.sign = '请选择角色身份标识';
    if (JSON.stringify(error) !== '{}') {
      await ctx.json(false, 'validate-error', error);
      return;
    }

    // 创建角色
    const newRole = await AdminRole.create({
      name,
      description,
      sign,
      permissions: permissions
    });

    if (newRole && newRole.id) {
      // 更新缓存中的权限数据
      initRedis();
      await ctx.json(true, '角色创建成功', newRole);
    } else {
      await ctx.json(false, '角色创建成功');
    }
  });

  /**
   * 修改角色
   * @param {String} name 角色名称
   * @param {String} sign 角色类型
   * @param {String} permissions 角色权限
   * @param {String} description 角色描述
   */
  router.put('/api/admin/role/:id', async ctx => {
    let { name = '', sign = 'user', description = '', permissions = [] } = ctx.request.body;
    const roleId = ctx.params.id;
    // 验证参数
    let error: AddRoleError = {};
    let params: AddRoleError = {};

    if (name) {
      if (!validator.isLength(name, { min: 2, max: 10 })) error.name = '角色名格式错误';
      if (await AdminRole.isRepeat('name', name, 'self')) error.name = '角色名重复';
      params.name = name;
    }
    if (sign) {
      params.sign = sign;
    }
    if (permissions) {
      if (permissions.length === 0) error.permissions = '请选择权限';
      params.permissions = permissions;
    }
    if (description || description === '') {
      params.description = description;
    }
    if (JSON.stringify(error) !== '{}') {
      await ctx.json(false, 'validate-error', error);
      return;
    }
    // 更新角色
    const updateResult = await AdminRole.update(params, { where: { id: roleId } });
    if (updateResult[0] === 1) {
      // 更新缓存中的权限数据
      initRedis();
      await ctx.json(true, '更新权限成功');
    } else {
      await ctx.json(false, '更新权限失败');
    }
  });

  /**
   * 删除权限
   */
  router.delete('/api/admin/role/:id', async ctx => {
    const { id } = ctx.params;
    // 校验是否有用户是当前角色
    const users = AdminUser.findAll({ where: { role_id: id } });
    if (users && users.length >= 1) {
      await ctx.json(false, '有用户仍为此角色，当前角色不可删除');
      return;
    }
    // 删除权限
    const deleteResult = await AdminRole.destroy({ where: { id } });
    await AdminAccessRouter.destroy({ where: { role_id: id } });
    if (deleteResult === 1) {
      // 更新缓存中的权限数据
      initRedis();
      await ctx.json(true, '删除权限成功');
    } else {
      await ctx.json(false, '删除权限失败');
    }
  });
}
